package com.matrix.codeGeneration.core;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import com.matrix.codeGeneration.model.CodeFile;
import com.matrix.codeGeneration.model.CodeModel;
import com.matrix.codeGeneration.model.OutDataSource;

import freemarker.template.Template;

/**
 * @author 姜友瑶
 * @e-mail:<935090232@qq.com>
 * @date 2015-10-23
 * @description 代码生成器
 */
public class Generator {

	public static void buildCodeFiles(OutDataSource outDataSource) {
		// 构建模型文件
		outDataSource.convertToTableModel();
		// 根据模型生成代码模型文件
		List<CodeFile> codeFileModel = generatorFile(outDataSource);
		// 根据模型文件生成实体文件
		createCodeFile(codeFileModel, outDataSource);
	}

	/**
	 * 创建要生成的所有文件的模型
	 * 
	 * @param configuration
	 * @return
	 */
	private static List<CodeFile> generatorFile(OutDataSource outDataSource) {
		List<CodeFile> codeFiles = new ArrayList<CodeFile>();
		Set<String> modelSet = outDataSource.getCodeModels().keySet();
		// 由模型来生成对应的codeFile，因为模型最知道自己需要的数据是什么，codeFile不关心数据
		for (String modelName : modelSet) {
			CodeModel codeModel = outDataSource.getCodeModels().get(modelName);
			List<CodeFile> thisModelFiles = codeModel.buildCodeFile(outDataSource);
			codeFiles.addAll(thisModelFiles);
		}
		return codeFiles;
	}

	/**
	 * 创建
	 * 
	 * @param configuration
	 * @param dbModel
	 * @return
	 */
	private static void createCodeFile(List<CodeFile> codeFiles, OutDataSource coutDataSource) {
		try {
			freemarker.template.Configuration cfg = new freemarker.template.Configuration();
			cfg.setLocale(Locale.SIMPLIFIED_CHINESE);
			cfg.setDefaultEncoding("utf-8");
			cfg.setEncoding(Locale.SIMPLIFIED_CHINESE, "utf-8");
			cfg.setEncoding(Locale.SIMPLIFIED_CHINESE, "utf-8");
			for (CodeFile codeFile : codeFiles) {
				Map<String, Object> root = new HashMap<String, Object>();
				// 设置文件需要的数据
				root.putAll(codeFile.getData());
				// 生成代码文件
				System.out.println("生成" + codeFile.getFileName() + "文件...");
				cfg.setDirectoryForTemplateLoading(new File(coutDataSource.getUserTempLataHome()));
				// 获取模板（template）
				Template template = cfg.getTemplate(codeFile.getTemplateName(), "utf-8");
				// 把文件写入磁盘
				String filePath = coutDataSource.getTargetPath() + codeFile.getSavePath();
				File file = new File(filePath);
				if (file.getParentFile().exists() && file.exists()) {
					File javaBean = new File(filePath + codeFile.getFileName());
					javaBean.createNewFile();
					BufferedWriter bf = new BufferedWriter(new FileWriter(javaBean));
					template.process(root, bf);
					bf.flush();
					bf.close();
				} else {
					if (file.mkdirs()) {
						File javaBean = new File(filePath + codeFile.getFileName());
						javaBean.createNewFile();
						BufferedWriter bf = new BufferedWriter(new FileWriter(javaBean));
						template.process(root, bf);
						bf.flush();
						bf.close();
					} else {
						System.out.println("创建文件失败" + filePath);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}